package com.aspire.boc.mms.wmf.permission;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.aspire.boc.mms.wmf.constants.GlobalConstant;
import com.aspire.boc.mms.wmf.dao.wmf.WmfActionMapper;
import com.aspire.boc.mms.wmf.dao.wmf.WmfResourceMapper;
import com.aspire.boc.mms.wmf.model.SecurityData;
import com.aspire.boc.mms.wmf.model.SecurityGroup;
import com.aspire.boc.mms.wmf.model.SecurityGroupUserRelation;
import com.aspire.boc.mms.wmf.model.SecurityUser;
import com.aspire.boc.mms.wmf.model.WmfAction;
import com.aspire.boc.mms.wmf.model.WmfActionExample;
import com.aspire.boc.mms.wmf.model.WmfResource;
import com.aspire.boc.mms.wmf.model.WmfResourceExample;
import com.aspire.boc.mms.wmf.model.WmfResourceExample.Criteria;
import com.aspire.boc.mms.wmf.service.PermissionService;
import com.aspire.boc.mms.wmf.util.Configuration;
import com.aspire.boc.mms.wmf.util.EhcacheUtil;
import com.aspire.boc.mms.wmf.util.LocalSecurityLoader;
import com.aspire.boc.mms.wmf.util.enums.ActionOwnerType;

@Component
public class PermissionCacheService {
	private  Log log = LogFactory.getLog(PermissionCacheService.class);
	@Autowired
	private PermissionService permissionService;
	@Autowired
	private WmfResourceMapper resourceMapper;
	@Autowired
	private WmfActionMapper wmfActionMapper;
	
	/**
	 * 缓存加载
	 */
	@PostConstruct
	public void load(){
		loadResourcesCache();
		loadActionsCache();
		loadSecurity();
	}
	
	/**
	 * 获取所有资源
	 * @Title: getResourcesCache 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<WmfResource> getResourcesCache(){
		Object o = EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE,GlobalConstant.RESOURCE_CACHE);
		return (List<WmfResource>) o;
	}
	
	/**
	 * 获取缓存的菜单信息(Map形式)
	 * @return
	 */
	public Map<Integer, WmfResource> getResourceCacheMap() {
		
		List<WmfResource>resourceCacheList = getResourcesCache();
		if(resourceCacheList == null || resourceCacheList.size() == 0) {
			return new HashMap<Integer, WmfResource>(0);
		}
		Map<Integer, WmfResource> resourceCacheMap = new HashMap<Integer, WmfResource>();
		for(WmfResource resource : resourceCacheList) {
			resourceCacheMap.put(resource.getId(), resource);
		}
		return resourceCacheMap;
	}
	
	/**
	 * 获取所有功能项
	 * @Title: getWmfActionsCache 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<WmfAction> getWmfActionsCache(){
		Object o = EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE,GlobalConstant.RESOURCE_CACHE);
		return (List<WmfAction>) o;
	}
	
	/**
	 * 
	 * @Title: getResourcesActionId 
	 * @Description: TODO(操作编号获取菜单,每一层的子菜单,
	 * Foundation为权限管理，，，，非管理员不包含权限管理资源) 
	 * @param actionIds
	 * @param pid 
	 * @return
	 */
	public List<WmfResource> getResourcesActionId(List<Integer> actionIds, String pid,Boolean isAdmin){
		List<WmfResource> resources = new ArrayList<WmfResource>();
		List<WmfResource> allResources = getResourcesCache();
		for(WmfResource resource : allResources){
			if(resource.getParentid().intValue() != Integer.parseInt(pid)){
				continue;
			}
			for(WmfAction wmfAction : resource.getWmfActions()){
				// 拥有菜单访问权限，才可判定为拥有菜单权限
				ActionOwnerType ownerType = ActionOwnerType.getByKey(wmfAction.getOwnertype());
				if(ownerType != null && ownerType.equals(ActionOwnerType.FRAMEWORK) && actionIds.contains(wmfAction.getId())){
					resources.add(resource);
					break;
				}
			}
		}
		return  resources; 
	}
	
	/**
	 * 
	 * @Title: getActionsResourceId 
	 * @Description: TODO(根据资源获取按钮) 
	 * @param id
	 * @param ownertype  按钮的等级，所在位置
	 * @return
	 */
	public  List<WmfAction> getActionsResourceId(Integer id,String ownertype){
		List<WmfAction> wmfActions = new ArrayList<WmfAction>();
		List<WmfResource> resources = getResourcesCache();
		for(WmfResource resource : resources){
			if(resource.getId().intValue() == id.intValue()){
				for(WmfAction wmfAction : resource.getWmfActions()){
					for(String owString : ownertype.split(",")){
						if(wmfAction.getOwnertype().intValue()==Integer.parseInt(owString)){
							wmfActions.add(wmfAction);
						}
					}
				}
			}
		}
		return wmfActions;
	}
	
	/**
	 * * @Description: TODO(根据所有者获取按钮) 
	 * @param ownertype
	 * @return
	 */
	public  List<WmfAction> getActionsOwnerType(String ownertype){
		List<WmfAction> wmfActions = new ArrayList<WmfAction>();
		List<WmfResource> resources = getResourcesCache();
		for(WmfResource resource : resources){
			for(WmfAction wmfAction : resource.getWmfActions()){
				if(wmfAction.getOwnertype().intValue()==Integer.parseInt(ownertype)){
					wmfActions.add(wmfAction);
				}
			}
		}
		return wmfActions;
	}
	
	/**
	 * 根据父节点获取所有所有
	 * @Title: getResourcesPid 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param pid
	 * @return
	 */
	public List<WmfResource> getResourcesPid(String pid,boolean isAdmin){
		List<WmfResource> resources = new ArrayList<WmfResource>();
		List<WmfResource> allResources = getResourcesCache();
		for(WmfResource resource : allResources){
			if(resource.getParentid().intValue() == Integer.parseInt(pid)){
				resources.add(resource);
			}
		}
		return  resources; 
	}
	
	/**
	 * 
	 * @Title: getResourcesActionId 
	 * @Description: TODO(根据按钮获取所有资源集合) 
	 * @param actionIds
	 * @return
	 */
	public List<WmfResource> getResourcesActionId(List<Integer> actionIds){
		List<WmfResource> resources = new ArrayList<WmfResource>();
		List<WmfResource> allResources = getResourcesCache();
		for(WmfResource resource : allResources){
			for(WmfAction wmfAction : resource.getWmfActions()){
				if(actionIds.contains(wmfAction.getId())){
					resources.add(resource);
					break;
				}
			}
		}
		return  resources; 
	}
	
	/**
	 * 
	 * @Title: loadResourcesCache 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @return
	 */
	private List<WmfResource> loadResourcesCache(){
	    
	    WmfResourceExample resourceExample = new WmfResourceExample();
	    resourceExample.setOrderByClause(" ORDERID ");
	    Criteria criteria = resourceExample.createCriteria();
	    // 只加载当前项目及基础框架菜单
	    String currentProjectName = Configuration.getConfiguration("system.current.project.name");
	    String frameworkProjectName = Configuration.getConfiguration("system.framework.project.name");
	    List<String> projectsNeedLoadResources = new ArrayList<String>(2);
	    if(StringUtils.isNotBlank(currentProjectName)) {
	    	projectsNeedLoadResources.add(StringUtils.trim(currentProjectName));
	    } 
	    if(StringUtils.isNotBlank(frameworkProjectName)) {
	    	projectsNeedLoadResources.add(StringUtils.trim(frameworkProjectName));
	    } 
	    criteria.andStatusEqualTo((short) 1);
	    if(!frameworkProjectName.isEmpty()) {
	    	criteria.andProjectNameIn(projectsNeedLoadResources);
	    }
		List<WmfResource> resources = resourceMapper.selectByExample(resourceExample);
		Map<Integer, WmfResource> resourceMap = new LinkedHashMap<Integer, WmfResource>();
		for(WmfResource resource : resources){
			List<WmfAction> wmfActions = permissionService.queryActionByRId(resource.getId());
			resource.setWmfActions(wmfActions);
			resourceMap.put(resource.getId(), resource);
		}
		EhcacheUtil.putValue(EhcacheUtil.CONFIG_CACHE, GlobalConstant.RESOURCE_CACHE, resources);
		EhcacheUtil.putValue(EhcacheUtil.CONFIG_CACHE, GlobalConstant.RESOURCE_MAP_CACHE, resourceMap);
		log.info(">>>>>>>>InitPermissionCache 加载菜单配置到缓存完成("+  EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE , 
				GlobalConstant.RESOURCE_CACHE)  +")");
		return resources;
	}
	
	/**
	 * 获取本地权限缓存
	 * @return
	 */
	public SecurityData getSecurityDataCache(){
		
		return (SecurityData) EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE,GlobalConstant.SECURITY_DATA_CACHE);
	}
	
	public SecurityUser getSecurityUserByLoginName(String loginName) {
		
		if(loginName == null) {
			return null;
		}
		SecurityData securityDataCache = getSecurityDataCache();
		if(securityDataCache == null) {
			return null;
		}
		Map<String, SecurityUser> userMap = securityDataCache.getUserMap();
		if(userMap == null) {
			return null;
		}
		return userMap.get(loginName);
	}
	
	public List<SecurityGroup> getGroupsByLoginName(String loginName) {
		
		SecurityData securityDataCache = getSecurityDataCache();
		if(securityDataCache == null) {
			return null;
		}
		return securityDataCache.getUserGroupMap().get(loginName);
	}
	
	/**
	 * 
	 * @Title: loadActionsCache 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @return
	 */
	private List<WmfAction> loadActionsCache(){
	    
	    WmfActionExample wmfActionExample = new WmfActionExample();
        com.aspire.boc.mms.wmf.model.WmfActionExample.Criteria criteria = wmfActionExample.createCriteria();
        criteria.andStatusEqualTo((short) 1);
        // 只加载当前项目及基础框架action
	    String currentProjectName = Configuration.getConfiguration("system.current.project.name");
	    String frameworkProjectName = Configuration.getConfiguration("system.framework.project.name");
	    List<String> projectsNeedLoadResources = new ArrayList<String>(2);
	    if(StringUtils.isNotBlank(currentProjectName)) {
	    	projectsNeedLoadResources.add(StringUtils.trim(currentProjectName));
	    } 
	    if(StringUtils.isNotBlank(frameworkProjectName)) {
	    	projectsNeedLoadResources.add(StringUtils.trim(frameworkProjectName));
	    } 
	    if(!frameworkProjectName.isEmpty()) {
	    	criteria.andProjectNameIn(projectsNeedLoadResources);
	    }
		List<WmfAction> wmfActions = wmfActionMapper.selectByExample(wmfActionExample);
		Map<Integer, WmfAction> actionMap = new LinkedHashMap<Integer, WmfAction>();
		for(WmfAction action : wmfActions){
			actionMap.put(action.getId(), action);
		}
		EhcacheUtil.putValue(EhcacheUtil.CONFIG_CACHE, GlobalConstant.ACTION_CACHE, wmfActions);
		EhcacheUtil.putValue(EhcacheUtil.CONFIG_CACHE, GlobalConstant.ACTION_MAP_CACHE, actionMap);
		log.info(">>>>>>>>InitPermissionCache 加载功能项到缓存完成("+  EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE , 
				GlobalConstant.RESOURCE_CACHE)  +")");
		return wmfActions;
	}
	
	/**
	 * 加载本地权限
	 */
	private void loadSecurity(){
		
		SecurityData securitydata = LocalSecurityLoader.getSecuritydata();
		EhcacheUtil.putValue(EhcacheUtil.CONFIG_CACHE, GlobalConstant.SECURITY_DATA_CACHE, securitydata);
		log.info(">>>>>>>>InitPermissionCache 加载本地权限到缓存完成("+  EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE , 
				GlobalConstant.SECURITY_DATA_CACHE)  +")");
	}
	
	/**
	 * 获取授权的菜单ID集合
	 * @param acitonsIds 授权的操作ID集合
	 * @return
	 */
	public List<Integer> getAuthorizedResourcesIds(List<Integer> acitonIds) {
	
		List<WmfResource> authorizedResources = getAuthorizedResources(acitonIds);
		if(authorizedResources == null || authorizedResources.isEmpty()) {
			return new ArrayList<Integer>(0);
		}
		List<Integer> authorizedResourceIds = new ArrayList<Integer>(authorizedResources.size());
		for(WmfResource resource : authorizedResources) {
			Integer resourceId = resource.getId();
			if(!authorizedResourceIds.contains(resourceId)) {
				authorizedResourceIds.add(resourceId);
			}
		}
		return authorizedResourceIds;
	}
	
	/**
	 * 获取授权的菜单ID集合
	 * @param acitonsIds 授权的操作ID集合
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<WmfResource> getAuthorizedResources(List<Integer> acitonIds) {
		
		if(acitonIds == null) {
			return new ArrayList<WmfResource>(0);
		}
		Map<Integer, WmfAction> actionMap = 
				(Map<Integer, WmfAction>) EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE , GlobalConstant.ACTION_MAP_CACHE);
		Map<Integer, WmfResource> resourceMap = 
				(Map<Integer, WmfResource>) EhcacheUtil.getValue(EhcacheUtil.CONFIG_CACHE , GlobalConstant.RESOURCE_MAP_CACHE);
		List<WmfResource> authResources = new ArrayList<WmfResource>();
		for(Integer actionId : acitonIds) {
			if(!actionMap.containsKey(actionId)) {
				continue;
			}
			WmfAction action = actionMap.get(actionId);
			if(!ActionOwnerType.FRAMEWORK.equals(ActionOwnerType.getByKey(action.getOwnertype()))) {
				continue;
			}
			Integer resourceId = action.getResourceId();
			findAuthrizedParentResources(resourceId, authResources, actionMap, resourceMap);
		}
		return authResources;
	}
	
	private void findAuthrizedParentResources(Integer resourceId, List<WmfResource> authResources, Map<Integer, WmfAction> actionMap, Map<Integer, WmfResource> resourceMap) {
		
		if(resourceId == null || !resourceMap.containsKey(resourceId)) {
			return;
		}
		WmfResource resource = resourceMap.get(resourceId);
		if(resource == null) {
			return;
		}
		if(!authResources.contains(resource)) {
			authResources.add(resource);
		}
 		findAuthrizedParentResources(resource.getParentid().intValue(), authResources, actionMap, resourceMap);
	}
	
}
